﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Speech.Synthesis;
using System.Threading;
using System.Windows.Forms;
using AR.Drone.Data.Navigation;
using AvionicsInstrumentControlDemo;
using DirecxPictureBox;
using isDrone;
using System.Drawing.Imaging;
using System.Linq;

namespace IsDroneApp
{
    public partial class Form1 : Form
    {
       Server s = new Server();
        Server sv = new Server();
        private DroneVideo videoControl;
        private ISDrone drone;
        private AltimeterInstrumentControl c;
        List<int[]> _batspeack = new List<int[]>{
                new[]  {50, 0},new[] {30, 0},new[] {20, 0},new[] {15, 0},new[] {10, 0},new[] {9, 0},new[] {8, 0},
                 new[] {7, 0},new[] {6, 0},new[] {5, 0},new[] {4, 0},new[] {3, 0},new[] {2, 0},new[] {1, 0},new[] {0, 0}
                };

        public Form1()
        {
            InitializeComponent();
            drone = new ISDrone();
   
            drone.Video.NewFrame += NewFrame;
            drone.Telemetry.NewTelemetry += SetTelemetrit;
            drone.Telemetry.NewNavdata += SetNavDate;
            drone._input.SetMin += SetMin;
            drone._input.SetPlus += SetMin;
            videoControl = new DroneVideo
            {
                Dock = DockStyle.Fill,
                Parent = videoPanel,
                SizeMode = PictureBoxSizeMode.Zoom
            };
            videoControl.MouseDoubleClick += videoPanel_MouseDoubleClick;
            drone._input.FullScrean += FullScran;

            s = new Server();
            var t = new Thread(s.StartListening);
            t.Start(11000);
            sv = new Server();
            var tv = new Thread(sv.StartListening);
            tv.Start(12000);
            Jpeginit();

        }

        public void SetMin()
        {
            videoControl.Procent =Convert.ToInt32 (drone.TanKrenK*100);
        }

        public void EnterFullScreenMode(Form targetForm)
        {
            targetForm.WindowState = FormWindowState.Normal;
            targetForm.FormBorderStyle = FormBorderStyle.None;
            targetForm.WindowState = FormWindowState.Maximized;
        }

        public void LeaveFullScreenMode(Form targetForm)
        {
            targetForm.FormBorderStyle = FormBorderStyle.Sizable;
            targetForm.WindowState = FormWindowState.Normal;
        }

        public void SmalScreenMode(Form targetForm)
        {
            targetForm.WindowState = FormWindowState.Normal;
            targetForm.FormBorderStyle = FormBorderStyle.None;
            targetForm.WindowState = FormWindowState.Normal;
            targetForm.Left = 0;
            targetForm.Top = 0;
            targetForm.Width = 640;
            targetForm.Height = 360;
        }

       
        public void SetTelemetrit()
        {
            StateDrone state = new StateDrone();

            state.Tangag = drone.Telemetry.Date.Pitch;
            state.Kren = drone.Telemetry.Date.Roll;
            state.Yau = (float)(drone.Telemetry.Date.Yaw / Math.PI * 180);
            state.Altitude = Convert.ToInt32(drone.Telemetry.Date.Altitude * 100);
            state.Speed = new[]
             {drone.Telemetry.Date.Velocity.X, drone.Telemetry.Date.Velocity.Y, drone.Telemetry.Date.Velocity.Z};
            state.WiFi = Convert.ToInt32(5 * drone.Telemetry.Date.Wifi.LinkQuality);
            state.Battarey = Convert.ToInt32(drone.Telemetry.Date.Battery.Percentage);
            state.FlyTime = Convert.ToInt32(drone.Telemetry.getFlyTime());
            state.EndTime = Convert.ToInt32(drone.Telemetry.EndTime());
            state.TotalTime = Convert.ToInt32(drone.Telemetry.TotalTime());
            state.Bootstrap = drone.Telemetry.Date.State.HasFlag(NavigationState.Bootstrap);
            state.Emergency = drone.Telemetry.Date.State.HasFlag(NavigationState.Emergency);
            state.Flying = drone.Telemetry.Date.State.HasFlag(NavigationState.Flying);
            videoControl.Hovering = drone.Telemetry.Date.State.HasFlag(NavigationState.Hovering);
            state.Landed = drone.Telemetry.Date.State.HasFlag(NavigationState.Landed);
            state.Landing = drone.Telemetry.Date.State.HasFlag(NavigationState.Landing);
            state.Takeoff = drone.Telemetry.Date.State.HasFlag(NavigationState.Takeoff);
            state.Wind = drone.Telemetry.Date.State.HasFlag(NavigationState.Wind);
            state.Mode = drone.modes[(drone.mode ? 1 : 0)] + (drone.magneto ? "+ Только Поворот" : "");
            s.SetState(state);

            videoControl.Tangag = drone.Telemetry.Date.Pitch;
            videoControl.Kren = drone.Telemetry.Date.Roll;
            videoControl.Yau =(float)( drone.Telemetry.Date.Yaw/Math.PI*180);
            videoControl.Altitude =Convert.ToInt32( drone.Telemetry.Date. Altitude*100);
            videoControl.Speed = new[]
            {drone.Telemetry.Date.Velocity.X, drone.Telemetry.Date.Velocity.Y, drone.Telemetry.Date.Velocity.Z};
            videoControl.WiFi = Convert.ToInt32(5* drone.Telemetry.Date.Wifi.LinkQuality);
            videoControl.Battarey = Convert.ToInt32(drone.Telemetry.Date.Battery.Percentage);
            videoControl.FlyTime = Convert.ToInt32(drone.Telemetry.getFlyTime());
            videoControl.EndTime = Convert.ToInt32(drone.Telemetry.EndTime());
            videoControl.TotalTime = Convert.ToInt32(drone.Telemetry.TotalTime()); 
            videoControl.Bootstrap = drone.Telemetry.Date.State.HasFlag(NavigationState.Bootstrap);
            videoControl.Emergency = drone.Telemetry.Date.State.HasFlag(NavigationState.Emergency);
            videoControl.Flying = drone.Telemetry.Date.State.HasFlag(NavigationState.Flying);
            videoControl.Hovering = drone.Telemetry.Date.State.HasFlag(NavigationState.Hovering);
            videoControl.Landed = drone.Telemetry.Date.State.HasFlag(NavigationState.Landed);
            videoControl.Landing = drone.Telemetry.Date.State.HasFlag(NavigationState.Landing);
            videoControl.Takeoff = drone.Telemetry.Date.State.HasFlag(NavigationState.Takeoff);
            videoControl.Wind = drone.Telemetry.Date.State.HasFlag(NavigationState.Wind);
            videoControl.Mode = drone.modes[(drone.mode?1:0)] + (drone.magneto ? "+ Только Поворот" : "");
            videoControl.Refresh();
            for (int i = 0; i < _batspeack.Count - 1; i++)

                if (_batspeack[i][1] == 0 && drone.Telemetry.Date.Battery.Percentage <=_batspeack[i][0] &&
                    drone.Telemetry.Date.Battery.Percentage>_batspeack[i + 1][0])
                {
                    _batspeack[i][1] = 1;
                    Speach(_batspeack[i][0]);

                }
        }

        public void Speach(object text)
        {
            bool eng = System.Threading.Thread.CurrentThread.CurrentUICulture.EnglishName == "en";
   var speaker = new SpeechSynthesizer();

            string t = "";
              foreach (InstalledVoice voice in speaker.GetInstalledVoices(System.Globalization.CultureInfo.CurrentUICulture))
        t=voice.VoiceInfo.Name;
        
            if (t!="")
            speaker.SelectVoice(t);
            speaker.Rate = 1;
            speaker.Volume = 100;
            speaker.SpeakAsync((int)text+(eng?" percent":" процентов"));
        }
        public void SetNavDate()
        {
            videoControl.Rec = Convert.ToInt32(drone.Telemetry.navdataBag.hdvideo_stream.hdvideo_state);
            videoControl.State = Convert.ToInt64(drone.Telemetry.navdataBag.ardrone_state);
            videoControl.UsbTime = Convert.ToInt32(drone.Telemetry.navdataBag.hdvideo_stream.usbkey_remaining_time);
      
        }


        private void Jpeginit()
        {
            _jgpEncoder = GetEncoder(ImageFormat.Jpeg);
            Encoder myEncoder = Encoder.Quality;
            _myEncoderParameters = new EncoderParameters(1);
            var myEncoderParameter = new EncoderParameter(myEncoder, 50L);
            _myEncoderParameters.Param[0] = myEncoderParameter;
        }
        private ImageCodecInfo GetEncoder(ImageFormat format)
        {
            ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();
            return codecs.FirstOrDefault(codec => codec.FormatID == format.Guid);
        }



        private System.Drawing.Imaging.ImageCodecInfo _jgpEncoder;
        private EncoderParameters _myEncoderParameters;

        private int _frame;

        private void NewFrame(Bitmap bitmap)
        {

        
         

            // var фотоАвтоПамять1 = new System.IO.MemoryStream();

            // bitmap.Save(фотоАвтоПамять1, _jgpEncoder, _myEncoderParameters);
            //sv.SetDate(  фотоАвтоПамять1.ToArray());


            _frame++;
           
            var t = new Thread(NewFrameO);
            t.Start(bitmap);


        }


        private void NewFrameO(object bitmap)
        {
           videoControl.ShowImage((Bitmap)bitmap);


            if (videoControl.Rect.Width > 0 && videoControl.Rect.Height > 0)
            {
                Bitmap b = new Bitmap(videoControl.Rect.Width, videoControl.Rect.Height);
                try
                {

                    Graphics graphics = Graphics.FromImage(b as Image);
                    graphics.CopyFromScreen(Left + videoPanel.Left + videoControl.Rect.Left, Top + videoPanel.Top + videoPanel.Top + videoControl.Rect.Top, 0, 0, b.Size);

                    var фотоАвтоПамять1 = new System.IO.MemoryStream();

                    b.Save(фотоАвтоПамять1, _jgpEncoder, _myEncoderParameters);
                    sv.SetDate(фотоАвтоПамять1.ToArray());

                }
                catch
                { }
                b.Dispose();
            }
        }

        //delegate void videoCallback(object bitmap);

        //private void VideoShow(object bitmap)
        //{
        //    if (!disposed && pictureBox1.InvokeRequired )
        //    {
        //        videoCallback d = VideoShow;
        //        Invoke(d, bitmap);
        //    }
        //    else
        //    {

        //        lock (vo)
        //        {
        //            if (!disposed)
        //            {
        //                frame++;
        //                System.Diagnostics.Stopwatch w = new System.Diagnostics.Stopwatch();
        //                w.Start();
        //                if (pictureBox1.Image != null)
        //                    pictureBox1.Image.Dispose();
        //                pictureBox1.Image = (Bitmap) bitmap;
                      
        //                w.Stop();
        //                Text = w.ElapsedMilliseconds.ToString();
        //            }

        //        }
        //    }

        //}


        private readonly object _vo = new object();


        private void переключениеToolStripMenuItem_Click(object sender, EventArgs e)
        {
            drone.Video.CamSet(true);
        }

        private void колибровкаToolStripMenuItem_Click(object sender, EventArgs e)
        {
            drone.Emergency();
        }

        private void взлетToolStripMenuItem_Click(object sender, EventArgs e)
        {
            drone.Takeoff();
        }

        private void посадкаToolStripMenuItem_Click(object sender, EventArgs e)
        {
            drone.Land();
        }

        private void переколибровкаToolStripMenuItem_Click(object sender, EventArgs e)
        {
            drone.Reset();
        }

        private void настройкиToolStripMenuItem1_Click(object sender, EventArgs e)
        {

            var f = new SettingForm(drone);
            f.Show();
        }

        private void подключаниеToolStripMenuItem_Click(object sender, EventArgs e)
        {
            drone.Connect();

        }

        private DateTime lasttime;
    
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            lock (_vo)
            {
       
                drone.Dispose();
            }
            
        }

        private void Form1_KeyPress(object sender, KeyPressEventArgs e)
        {
            
        }
       
        private void videoPanel_Paint(object sender, PaintEventArgs e)
        {
            
        }

        private void videoPanel_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            FullScran();
        }
        delegate void Fs();

        private int wmode = 0;
        private void FullScran()
        {

            if (InvokeRequired)
            {
                Fs d = FullScran;
                Invoke(d);
            }
            else
            {
                if (wmode < 2) wmode++;
                else wmode = 0;
                if (wmode == 0)
                {
                    menuStrip1.Visible = true;
                    FormBorderStyle = FormBorderStyle.Sizable;
                    WindowState = FormWindowState.Normal;
                }
                if (wmode == 1)
                {
                    menuStrip1.Visible = false;
                    WindowState = FormWindowState.Normal;
                    FormBorderStyle = FormBorderStyle.None;
                    WindowState = FormWindowState.Maximized;
                }
                if (wmode == 2)
                {
                    menuStrip1.Visible = false;
                    WindowState = FormWindowState.Normal;
                    FormBorderStyle = FormBorderStyle.None;
                    WindowState = FormWindowState.Normal;
                    Left = 0;
                    Top = 0;
                    Width = 640;
                    Height = 360;
                }

            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void справкаToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var f = new Form2();
            f.Show();
        }

        private void saveTelemetryToolStripMenuItem_Click(object sender, EventArgs e)
        {
            drone.Telemetry.Save();
        }

        private void телеметрияToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var t = new TelemetryForm(drone);
            t.Show();
        }

      
        private void button1_Click(object sender, EventArgs e)
        {
        
        }

        private void menuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {

        }
    }
}
